##
#
 
"""

The layout of the site uses the main template, which
consists of an HTML table which provides space for the
menu component and the body component.

Apache config:

  SetHandler mod_python
  PythonHandler mod_python.publisher

"""

# Ola osa exoun sxesh me ton server
from serverUtilities import *


########### SECTION SXOLIWN ###########################
#  1) buggia ... sthn epilogh twn kombwn prepei na pername kai to port. oxi mono thn ip
#  2) kapws prepei na exw to onoma tou server sthn morfh (ip, port). twra me to xeri (grammh 331)
#  3) mazi me to action prepei na pairnoume kai tis parametrous
#  4) gia debug kanoume print >> debug , MSG ... kai tail -f sto /tmp/debug.txt
#
#
#########################################################

#########################################################
############### CONST


# subdirectory where we place templates
TMPL_DIR = "templates"

# the name for the "shell" template
MAIN_TMPL = "main_frame.html"
# the menu template
MENU_TMPL = "main_menu.html"

__auth_realm__ = "Members only"

#debug = open('/tmp/debug.txt','a')
#resDebug = open('/tmp/resultNodes.txt','a')
# @@: This shouldn't be hardcoded; but including it only in the Apache
# config makes it hard for programs outside of Apache to access the
# secret.  It probably should be kept in a file.  Security of such a
# file is important, but it's not very important to protect such a
# file from a local exploit.
SECRET = 'myspecialsecret'
MYHOST = ("139.91.70.38" , 11224)

#######################################################
# Called when a new command need to be send




#########################################################
###############  Request handlers

def index(req):
    # The publisher will call this function as default,
    # make it same as home
    return home(req)


def home(req):
    return _any_page(req, 'home')

def product(req):
    return _any_page(req, 'product')

def about(req):
    return _any_page(req, 'about')

def node_manage(req):
    def __auth__(req, user, password):

        passwd= hexlify( EVP.hmac(user, password, algo='sha256')) 

        # Authendication
        # connect to DB
        db = create_engine('mysql://apache:apache@localhost/p2p')
        metadata = MetaData(db)
        # get the table
        users = Table('users', metadata, autoload=True, include_columns=['username','passwd'])

        #xm...
        db.echo = False  

        # dump everything
        s = users.select()

        lst = list(s.execute());
        for item in lst:
            if (item.username == user):
                if ( item.passwd == passwd ):
                    return 1;
                else:
                    return 0;


    return _any_page(req, 'node_manage')

def node_add(req, args=None):
    return _node_add_page(req, args)


def node_status(req):
    def __auth__(req, user, password):

        passwd= hexlify( EVP.hmac(user, password, algo='sha256')) 

        # Authendication
        # connect to DB
        db = create_engine('mysql://apache:apache@localhost/p2p')
        metadata = MetaData(db)
        # get the table
        users = Table('users', metadata, autoload=True, include_columns=['username','passwd'])
        #xm...
        db.echo = False  

        # dump everything
        s = users.select()

        lst = list(s.execute());
        for item in lst:
            if (item.username == user):
                if ( item.passwd == passwd ):
                    return 1;
                else:
                    return 0;



    return _node_status_page(req,'node_status')


def emergency(req):
    def __auth__(req, user, password):

        passwd= hexlify( EVP.hmac(user, password, algo='sha256')) 

        # Authendication
        # connect to DB
        db = create_engine('mysql://apache:apache@localhost/p2p')
        metadata = MetaData(db)
        # get the table
        users = Table('users', metadata, autoload=True, include_columns=['username','passwd'])

        #xm...
        db.echo = False  

        # dump everything
        s = users.select()

        lst = list(s.execute());
        for item in lst:
            if (item.username == user):
                if ( item.passwd == passwd ):
                    return 1;
                else:
                    return 0;

    return _emergency_page(req, 'emergency')



def file_transfer( req, nodeList=None , action=None, file=None, param=None , selected=None ):

    def __auth__(req, user, password):

        passwd= hexlify( EVP.hmac(user, password, algo='sha256')) 

        # Authendication
        # connect to DB
        db = create_engine('mysql://apache:apache@localhost/p2p')
        metadata = MetaData(db)
        # get the table
        users = Table('users', metadata, autoload=True, include_columns=['username','passwd'])

        #xm...
        db.echo = False  

        # dump everything
        s = users.select()

        lst = list(s.execute());
        for item in lst:
            if (item.username == user):
                if ( item.passwd == passwd ):
                    return 1;
                else:
                    return 0;


    if ( nodeList == None ):
        # connect to DB
        db = create_engine('mysql://apache:apache@localhost/p2p')
        metadata = MetaData(db)
        # get the table
        nodes = Table('nodes', metadata, autoload=True, include_columns=['ip', 'port'])


        db.echo = False  # Try changing this to True and see what happens

        pw = req.get_basic_auth_pw()
        user = req.user
        # dump everything
        if (user=='admin'):
            s = nodes.select();
        else:
            try:
                s = nodes.select(nodes.c.username==user);
            except:
                return " " 

        head = ""
        result = H_checkbox_form( ("nodeList"), "file_transfer", "Please select nodes to manage", "Go on" )

        try:
            lst = list(s.execute());
        except:
             return " " 

        #--------  Creating a List of nodes  ------------
        nodeList = [] # Keeping track of hosts in form of tuple
        for node in lst :
            try :
                host = (node[0] , int (node[1]))
                nodeList.append ( host )
            except :
                dummyNode = (None, None)
                nodeList.append( dummyNode )

        result.insert( nodeList )
        head =  result.print_table()
        #---------------------------------------------------


        vars = {"menu": _menu(req, hlight="tettt"),
               "body": head}

        main_tmpl = _tmpl_path(MAIN_TMPL)

        return psp.PSP(req, main_tmpl, vars=vars)

    # --------- Creating a list of results for each node -------------
    # FIXME : uparxei 8ema me to oti to nodeList mporei na einai eite ths morfhs ["node1" , "node2"] eite (node1). den mporesa na diaxwrisw tous typoys opote to ekana me to mege8os

    # An uparxei action to ektelei. Alliws mas metaferei sto menu me
    # tis epiloges twn kombwn

    if action != None :
        if selected == None :
            selected = nodeList

        return _file_action( req, MYHOST , selected ,action, file, param )

    else :

        resultList = [] # Keeping results of each node
        stopLoop = 0

        for  host in nodeList  :
            try :
                if len( host ) == 1 :
                    host = nodeList
                    stopLoop = 1

                host = eval( host )                
                result = sendBetweenNode( MYHOST , host , "LS" ) 
            except :
                raise
            #result = "NoResults"
            
            resultList.append( result )
            if stopLoop == 1 : 
                break

        return _file_page(req, 'file_transfer', nodeList , resultList)
    return "Should Not Be Here"





#### These are for admin only

def add_user(req,username=None, password=None):
    # if not admin then deny access
    def __auth__(req, user, password):

        passwd= hexlify( EVP.hmac(user, password, algo='sha256')) 

        # Authendication
        # connect to DB
        db = create_engine('mysql://apache:apache@localhost/p2p')
        metadata = MetaData(db)
        # get the table
        users = Table('users', metadata, autoload=True, include_columns=['username','passwd'])

        #xm...
        db.echo = False  

        # dump everything
        s = users.select()

        lst = list(s.execute());
        for item in lst:
            if (item.username == user):
                if ( item.passwd == passwd ):
                    return 1;
                else:
                    return 0;




    def __access__(req, user):
   	 if user == "admin":
   	     return 1
   	 else:
   	     return 0

    if ( username==None or password==None ):
        return "<html> <FONT COLOR=\"FF0000\">Nice try...</FONT> </html>"  

    if ( username=='' or password=='' ):
        return _admin_page(req,'admin_preference', "<FONT COLOR=\"FF0000\">Username or Password is blank!</FONT> <br> " )

    return _add_user(req,username,password)


#--------------------------------------------------------------------------
def del_user(req,name=None):
#--------------------------------------------------------------------------
    # if not admin then deny access
    def __auth__(req, user, passwd):
        if user == "admin" and passwd == "admin":
            return 1
        else:
            return 0

    def __access__(req, user):
   	 if user == "admin":
   	     return 1
   	 else:
   	     return 0

    if ( name==None ):
        return "<html> <FONT COLOR=\"FF0000\">Nice try...</FONT> </html>"  

    if ( name=='' ):
        return _admin_page(req,'admin_preference', "<FONT COLOR=\"FF0000\">Username or Password is blank!</FONT> <br> " )

    return _del_user(req,name)




#--------------------------------------------------------------------------
def admin_preference(req):
#--------------------------------------------------------------------------
    def __auth__(req, user, password):

        passwd= hexlify( EVP.hmac(user, password, algo='sha256')) 

        # Authendication
        # connect to DB
        db = create_engine('mysql://apache:apache@localhost/p2p')
        metadata = MetaData(db)
        # get the table
        users = Table('users', metadata, autoload=True, include_columns=['username','passwd'])

        #xm...
        db.echo = False  

        # dump everything
        s = users.select()

        lst = list(s.execute());
        for item in lst:
            if (item.username == user):
                if ( item.passwd == passwd ):
                    return 1;
                else:
                    return 0;

    def __access__(req, user):
   	 if user == "admin":
   	     return 1
   	 else:
   	     return 0

    return _admin_page(req,'admin_preference')

#--------------------------------------------------------------------------
def test2(req,name=None):
#--------------------------------------------------------------------------
    data=" "
    if name != None:
	if isinstance(name,list):
            for item in name:
                data += "\n " +item
        else:
            data += name
        return data
    else:
         return "null!"

#########################################################
##
# Internal functions. Because they begin with an underscore,
# the publisher will not allow them to be accessible from the
# web. Perhaps a cleaner technique is to place these into a
# seprate module. If that module contains __access__ = 0 global
# variable, then none of its contents would be accessible via
# the publisher, in which case you don't need to prepend
# underscores to function names.


# generic
#--------------------------------------------------------------------------
def _base_url(req, ssl=1):
#--------------------------------------------------------------------------
    """
    This function makes its best effort to guess the base url.
    Sometimes it is simpler to just hard code the base url as
    a constant, but doing something like this makes the application
    independent of what the name of the site is.
    """
    
    # first choice is the 'Host' header, second is the
    # hostname in the Apache server configuration.
    host = req.headers_in.get('host', req.server.server_hostname)
    
    # are we running on an unusual port?
    if not ':' in host:
        port = req.connection.local_addr[1]
        if port != 80 and not ssl:
            host = "%s:%d" % (host, req.connection.local_addr[1])

    # SSL?        
    if ssl:
        base = 'https://' + host + req.uri
    else:
        base = 'http://' + host + req.uri

    # chop off the last part of the URL    
    return os.path.split(base)[0]

#--------------------------------------------------------------------------
def _tmpl_path(name):
#--------------------------------------------------------------------------
    """ A shorthand for building a full path to a template """
    return os.path.join(TMPL_DIR, name)

#--------------------------------------------------------------------------
def _admin_path(name):
#--------------------------------------------------------------------------
    """ A shorthand for building a full path to a template """
    return os.path.join(TMPL_DIR, name)

#--------------------------------------------------------------------------
def _menu(req, hlight, tmpl=MENU_TMPL):
#--------------------------------------------------------------------------
    """
    This function builds a menu. The actual menu contents is inside the
    PSP template whose file name is passed in as tmpl. The hlight string
    gives the menu an opportunity to highlight a particular menu item.
    """

    tmpl = _tmpl_path(tmpl)
    m = psp.PSP(req, tmpl, vars={'hlight':hlight})
    return m

#--------------------------------------------------------------------------
def _any_page(req, name):
#--------------------------------------------------------------------------
    """
    Construct a web page given a page name, which is a string identifier
    that is also passed to the _menu() function to highlight the current
    menu item, and is used to construct the filename for the page template.
    """

    body_tmpl = _tmpl_path('%s_body.html' % name)

    vars = {"menu": _menu(req, hlight=name),
            "body": psp.PSP(req, body_tmpl)}

    main_tmpl = _tmpl_path(MAIN_TMPL)

    return psp.PSP(req, main_tmpl, vars=vars)

### More specific
#--------------------------------------------------------------------------
def _file_page(req, name, nodeList=None , resultList=None):
#--------------------------------------------------------------------------
    """
    Construct a web page given a page name, which is a string identifier
    that is also passed to the _menu() function to highlight the current
    menu item, and is used to construct the filename for the page template.
    """

    body_tmpl = _tmpl_path('%s_body.html' % name)

    # Add global vars to body
    vars0 = {}
    vars0['resultList'] = resultList
    vars0['nodeList'] = nodeList

    vars = {"menu": _menu(req, hlight=name),
            "body": psp.PSP(req, body_tmpl,vars=vars0),
     }

    main_tmpl = _tmpl_path(MAIN_TMPL)

    return psp.PSP(req, main_tmpl, vars=vars)

#--------------------------------------------------------------------------
def _admin_page(req,name,extra=None):
#--------------------------------------------------------------------------

    body_tmpl = _tmpl_path('%s_body.html' % name)
    body = ""
    if (extra != None):
        body += extra;

    body +=" <P> <FORM method=\"post\" action=\"add_user\"   \
    <br>\
    Username: <INPUT type=\"text\" name=\"username\"><BR>\
    Password: <INPUT type=\"password\" name=\"password\"><BR>\
    <INPUT type=\"submit\" value=\"Add\"> <INPUT type=\"reset\"> \
    </form>\
    </P>"



    # connect to DB
    db = create_engine('mysql://apache:apache@localhost/p2p')
    metadata = MetaData(db)
    # get the table
    users = Table('users', metadata, autoload=True, include_columns=['username'])

    #xm...
    db.echo = False  # Try changing this to True and see what happens

    # dump everything
    s = users.select()

    result = H_checkbox_form( ("username" ), "del_user" ,"Select user to delete:", "Delete" )



    lst = list(s.execute());
    for item in lst:
        result.insert(item)

    body += result.print_table()



    vars = {"menu": _menu(req, hlight=name),
            "body": body}

    main_tmpl = _tmpl_path(MAIN_TMPL)

    return psp.PSP(req, main_tmpl, vars=vars)


#--------------------------------------------------------------------------
def _add_user(req,username=None,password=None):
#--------------------------------------------------------------------------
    # This check if something went wrong...
    if ( username == None or password == None):
        return "Internal Error..."


    # connect to DB
    db = create_engine('mysql://apache:apache@localhost/p2p')
    metadata = MetaData(db)
    # get the table
    t_users = Table('users', metadata, autoload=True)

    #xm...
    db.echo = False  # Try changing this to True and see what happens
    # dump everything


    ret= "Submited! Redirecting....: "

    data=""

    passwd= hexlify( EVP.hmac(username, password, algo='sha256')) 

    ins = t_users.insert((username,passwd, "","" ))
    try:
        ins.execute()
    except :
        return _admin_page(req,'admin_preference', "<FONT COLOR=\"FF0000\">Username conflict or... internal error in DB !</FONT> <br> " )
    util.redirect(req, 'admin_preference')
    return ret;


#--------------------------------------------------------------------------
def _del_user(req,username=None):
#--------------------------------------------------------------------------
    # This check if something went wrong...
    if ( username == None ):
        return "Internal Error..."


    # connect to DB
    db = create_engine('mysql://apache:apache@localhost/p2p')
    metadata = MetaData(db)
    # get the table
    t_users = Table('users', metadata, autoload=True)

    #xm...
    db.echo = False  # Try changing this to True and see what happens


    del_u = t_users.delete(("username=\""+username+"\"" ))
    ret= "Submited! Redirecting....: Not yet!" 



    try:
        del_u.execute()
    except :
        return _admin_page(req,'admin_preference', "<FONT COLOR=\"FF0000\">Username ? or... internal error in DB !</FONT> <br> " )
 
    util.redirect(req, 'admin_preference')

    return ret;

# TODO : mixalh, o ka8e kombos na perigrafetai apo to tuple (ip, port)
# logos upar3hs me8odou ... aplws gia elegxous gia na 3efortwsei h called method
#--------------------------------------------------------------------------
def  _file_action(req,node1= (None,None) , node2=(None,None) ,action=None, *args):
#--------------------------------------------------------------------------
    
    # Checking the type of parameters
    argIsList = False
    if isinstance (args[0] , str ) :
        param = " " +  " ".join(args)

    elif isinstance(args[0] , list ) :
        argIsList = True
        param = " " +  " ".join(args[0])
    else :
        return "Wrong Type " , type(args[0])


    if action != "Delete" :
        if ( argIsList == True ) and (len( args[0] ) > 1)  :
            return "Too many files selected"


    if action == "Transfer" :
        selected = node2
        if len(selected ) != 2 :
            return "Please select nodes properly : " , selected

        fileName = args[0]
        source = eval(selected[0])
        destination = eval(selected[1])
        return sendBetweenNode ( source , destination , action , fileName )

    # Counting nodes
    if  node2[0] != '(' :
        if len(node2) != 1 :
            return "Wrong Number Of nodes selected : " , len(node2)
    else :
        node2 = eval(node2)
    
    if len(node2) == 1 :
        return "Please select at least one node"

    return sendBetweenNode( node1 , node2 , action , param )




#--------------------------------------------------------------------------
def _node_status_page(req,name):
#--------------------------------------------------------------------------
    # connect to DB
    db = create_engine('mysql://apache:apache@localhost/p2p')
    metadata = MetaData(db)
    # get the table
    nodes = Table('nodes', metadata, autoload=True)
    #xm...
    db.echo = False  # Try changing this to True and see what happens

    pw = req.get_basic_auth_pw()
    user = req.user
    # dump everything
    if (user=='admin'):
        s = nodes.select();
    else:
        s = nodes.select(nodes.c.username==user);
    head = user
    result = H_table( ("Node id", "Username", "IP", "PKEY", "Port", "Last emergency signal", "Emergency port"))

    lst = list(s.execute());
    nodeList = []
    for item in lst:
        result.insert(item)
        # Upo8etw pws item[2] einai h ip kai item[4] to port
        nodeList.append((str(item[2]), int(item[4])))

    head = result.print_table()
    body_tmpl = _tmpl_path('%s_body.html' % name)
    head += "<table border=\"1\">"
    head += "<tr> <td>Node IP</td> <td>Top result</td> </tr>"

    try :
        for node in nodeList :
            head = head + "<tr> <td>"
            head = head + str(node[0])
            head = head + "</td>"
            head = head + "<td>"
            head = head + sendBetweenNode( MYHOST , node , "STATUS" )
            head = head + "</td></td>"
    except :
        head = head + "Failed to connect"
    
    head += "</table>"

    head = str(head)
    # Add global vars to body
    vars0 = {
             'result': head,
	 }


    vars = {"menu": _menu(req, hlight=name),
            "body": psp.PSP(req, body_tmpl,vars=vars0),
    }

    main_tmpl = _tmpl_path(MAIN_TMPL)

    return psp.PSP(req, main_tmpl, vars=vars)



    main_tmpl = _tmpl_path(MAIN_TMPL)

    return psp.PSP(req, main_tmpl, vars=vars)


#--------------------------------------------------------------------------
def _emergency_page(req,name):
#--------------------------------------------------------------------------
    # connect to DB
    db = create_engine('mysql://apache:apache@localhost/p2p')
    metadata = MetaData(db)
    # get the table
    nodes = Table('nodes', metadata, autoload=True)
    #xm...
    db.echo = False  # Try changing this to True and see what happens

    pw = req.get_basic_auth_pw()
    user = req.user
    # dump everything
    if (user=='admin'):
        s = nodes.select(nodes.c.emergency!='');
    else:
        s = nodes.select((nodes.c.username==user,nodes.c.emergency!=''));

    head = user
    result = H_table( ("Node id", "Username", "IP", "PKEY", "Port", "Last emergency signal", "Emergency port"))

    try:
        lst = list(s.execute());
    except :
        lst = ()

    nodeList = []
    for item in lst:
        result.insert(item)
        # Upo8etw pws item[2] einai h ip kai item[4] to port
        nodeList.append((str(item[2]), int(item[4]),str(item[6])))

    head = result.print_table()
    body_tmpl = _tmpl_path('%s_body.html' % name)
    
    head = str(head)
    # Add global vars to body
    vars0 = {
             'result': head,
	 }


    vars = {"menu": _menu(req, hlight=name),
            "body": psp.PSP(req, body_tmpl,vars=vars0),
    }

    main_tmpl = _tmpl_path(MAIN_TMPL)

    return psp.PSP(req, main_tmpl, vars=vars)



    main_tmpl = _tmpl_path(MAIN_TMPL)

    return psp.PSP(req, main_tmpl, vars=vars)

#--------------------------------------------------------------------------
def _node_add_page(req,name):
#--------------------------------------------------------------------------
    # connect to DB
    db = create_engine('mysql://apache:apache@localhost/p2p')
    metadata = MetaData(db)
    # get the table
    nodes = Table('nodes', metadata, autoload=True, include_columns=['ip'])

    #xm...
    db.echo = False  # Try changing this to True and see what happens

    # dump everything
    s = nodes.select("nodes.username=''")

    head = ""
    result = H_checkbox_form( ("username" ),"test2" ,"Please select node:", "Add node")



    lst = list(s.execute());
    for item in lst:
        result.insert(item)

    head = result.print_table()

    vars = {"menu": _menu(req, hlight=name),
           "body": head}

    main_tmpl = _tmpl_path(MAIN_TMPL)

    return psp.PSP(req, main_tmpl, vars=vars)





#####################################
######### Some other classes 


# Class checkbox list :  Creates a checkbox list with 
#                        with the available nodes


class H_checkbox_form:

    #--------------------------------------------------------------------------
    def __init__( self, names, post_url="test2", title=" ", button="execute", name = None ):
    #--------------------------------------------------------------------------
        self.button=button;
        self.data="<form method=\"post\" action=\"" + post_url + "\"> " + title + " : \
             <br><br>     "
     		

    def insert(self, list):
        i = 0 
        for item in list:
            nodeName = "node" + str(i)
            i = i + 1
            self.data += " <input type=\"checkbox\" name=\"nodeList\"  value=\"" +  str(item) + "\">" + str(item) + "<br> \n"
        


    def print_table(self):
        return self.data + "       <br> \
                                    <input type=\"submit\" value=\" " + self.button + "\"> \
                                   <br> \
                              </form> "



####### Class table:  Creates a table with fixed number of columns
#######               someone can insert rows and later print them

class H_table:

    #--------------------------------------------------------------------------
    def __init__( self, names ):
    #--------------------------------------------------------------------------
  

        self.data="	<p> 							\n\
									\n\
	<h3>Node status</h3>						\n\
									\n\
	<p> <TABLE border=\"1\" cellspacing=\"1\" cellpadding=\"1\" > 	\n\
		<caption>Node status</caption>				\n\
		<TR>							\n\
        "
		
        for item in names:
            self.data +=  "<TD align=center >" + item +"</TD>		\n "

        self.data +="	</TR>						\n "



    def insert(self, list):
        self.data +=  "<TR> \n" 
        for item in list:
            self.data += "	<TD align=center>" + str(item) + "</TD> \n"
        
        self.data +=  "</TR> \n" 


    def print_table(self):
        return self.data + "       </TABLE> ";


####### Class R_table:  Select node for file transfer

class R_table:
    #--------------------------------------------------------------------------
    def __init__( self, names, post_url="test2", title=" ", button="execute", name = None ):
    #--------------------------------------------------------------------------
        self.button=button;
        self.data="<form method=\"post\" action=\"" + post_url + "\"> " + title + " : \
             <br><br>    <table><tr> <td > "
     		

    def insert1(self, item):
       # for item in list:
        self.data += "<input type=\"radio\" name=\"node1\" value=\"" + str(item) + "\"> " + str(item)+  "<br> \n"

    def insert_limit(self):
        self.data += "\n </td> <td>  \n"
        
    def insert2(self, item):
        #for item in list:
            self.data += "<input type=\"radio\" name=\"node2\" value=\"" + str(item) + "\"> " + str(item)+  "<br> \n"


    def print_table(self):
        return self.data + "     </td> </tr>  </table>   <br> \
                                    <input type=\"submit\" value=\" " + self.button + "\"> \
                                   <br> \
                              </form> "





########################################################
## DEAD CODE !! FIXME: Do we need it ??? 

def headerparserhandler(req):
    """
    The actual authenticating check.  This checks if there is a proper
    cookie in the request, and sets the request based on that.  It
    also clears out any attempt to do HTTP Basic authentication.

    The cookie should look like sig:user_enc, where user_enc is the
    username encoded in base64.  The signature is the secret (SECRET
    at the top of this file) concatenated with the unencoded username.
    """
    # First we clear out any stale login information; we are in
    # this process disallowing HTTP Basic login, because we are
    # actually avoiding doing any password checking here.
    req.user = ''
    cookies = Cookie.get_cookies(req)
    if cookies.has_key('authinfo'):
        authinfo = cookies['authinfo'].value
        # We decode the cookie and confirm the signature,
        # lastly setting the username.
        try:
            if ':' not in authinfo:
                raise ValueError, "Badly formatted cookie"
            sig, username = authinfo.split(':', 1)
            username = username.decode('base64')
            if md5.new(SECRET + username).hexdigest() != sig:
                raise ValueError, "Bad cookie signature"
            req.user = username
        except ValueError, msg:
            req.user = ''
    # We get rid of any spurious Authorization headers, and
    # put in a fake authorization header if there is a user
    # logged in.
    if req.user:
        req.headers_in['Authorization'] = (
            'Basic ' + (req.user  + ':').encode('base64'))
    else:
        if req.headers_in.has_key('Authorization'):
            del req.headers_in['Authorization']

    return check_authorization(req)

def check_authorization(req):
    """
    Checks if the user is authorized.  Currently the only restriction
    is PythonOption login_required yes; there's no other ways to
    restrict users.
    """
    ops = req.get_options()
    if (ops.get('login_required')
        and ops['login_required'].lower().startswith('y')):
        if not req.user:
            redir = ops.get('login_screen')
            if redir:
                req.internal_redirect(redir)
                return apache.OK
            else:
                return apache.HTTP_UNAUTHORIZED
    return apache.OK

def authorize_user_cookie(username):
    """
    Use like:
    print 'Set-Cookie: ' + authorize_user_cookie('bob')
    """
    sig = md5.new(SECRET + username).hexdigest()
    return 'authinfo=%s:%s; Path=/;' % (sig, username.encode('base64').strip())

def unauthorize_user_cookie():
    """
    Used for logout, like:
    print 'Set-Cookie: ' + unauthorize_user_cookie()
    """
    return ('authinfo=; Path=/; expires=%s' %
            time.strftime(time.gmtime(),
                          '%a, %d-%b-%Y %H:%M:%S GMT'))


def _auth_user(req,user,passwd):
    return 0



